﻿using System;
using System.Collections.Generic;
using System.Text;

namespace eslib.DataRetrievalLib
{

    public enum DRHandlerUnfeatureType
    {
        /// <summary>
        /// 不符合特征的进入输出流
        /// </summary>
        UNFEATURE_HEAD_ENQUEUE = 0,

        /// <summary>
        /// 不符合特征的不进入输出流
        /// </summary>
        UNFEATURE_HEAD_NON_ENQUEUE
    };




    /// <summary>
    /// 处理器
    /// </summary>
    public class DRHandler
    {
        /// <summary>
        /// 构造特征处理器
        /// </summary>
        /// <param name="controler"></param>
        /// <param name="unfeature_head_handle_type"></param>
        /// <param name="feature"></param>
        public DRHandler(DataRetrieval controler, DRHandlerUnfeatureType unfeature_head_handle_type, byte[] feature)
        {
            this.controler = controler;
            this.stream = controler.stream;
            this.unfeature_head_handle_type = unfeature_head_handle_type;
            this.feature = feature;

            is_unconditional_handler = false;       //false，非计数器	

            reset();
        }

        /// <summary>
        /// 构造无条件计数处理器
        /// </summary>
        /// <param name="controler"></param>
        /// <param name="count"></param>
        public DRHandler(DataRetrieval controler, int count)
        {
            this.controler = controler;
            this.stream = controler.stream;


            //无条件计数器
            is_unconditional_handler = true;       //true，计数器
            this.count = count;

            reset();
        }


        //重置处理器
        private void reset()
        {
            matche = -1;
            count_ptr = 0;

            tempForMatch = new List<byte>();
        }



        internal void inStream(byte ch)
        {
            //无条件计数器模式
            if (is_unconditional_handler)
            {
                //写入输出流
                stream.write(ch);
                count_ptr++;  //记录数量				

                if (count_ptr >= count)
                {
                    //已达到足够数量			
                    //重置
                    reset();

                    //引发事件		
                    controler.match_viewer();
                }

                //必需return;
                return;
            }


            /*
            特征匹配模式
            -1: 未匹配
            - 1<matche<len - 1 : 正在匹配
            matche == len - 1 : 匹配成功
            */
            if (feature[matche + 1] == ch)
            {
                //匹配
                matche++;

                //进入临时缓存
                tempForMatch.Add(ch);

                if (matche == feature.Length - 1)  //匹配成功
                {
                    //重置
                    reset();

                    //引发事件
                    controler.match_viewer();
                }
            }
            else
            {
                //不匹配
                switch (unfeature_head_handle_type)
                {
                    case DRHandlerUnfeatureType.UNFEATURE_HEAD_ENQUEUE:      //不符特征进入输出流
                        //如果之前有特征被匹配，写入之前的临时缓存,否则数据中间的0xff会被跳过
                        if (tempForMatch.Count > 0)
                        {
                            foreach (var tch in tempForMatch) stream.write(tch);
                            tempForMatch.Clear();
                            break;
                        }

                        stream.write(ch);
                        break;

                    case DRHandlerUnfeatureType.UNFEATURE_HEAD_NON_ENQUEUE:      //不符特征不进入输出流
                        break;
                }

                //当matche!=-1时重新进入匹配
                if (matche != -1)
                {
                    matche = -1;
                    this.inStream(ch);
                    return;
                }

                //还原matche
                matche = -1;
            }
        }



        private DataRetrieval controler;     //主控制器指针

        private stream stream;      //流控制器

        private DRHandlerUnfeatureType unfeature_head_handle_type;  //不符合特征的头部处理类型

        private byte[] feature;      //特征

        //无条件计数器
        bool is_unconditional_handler;        //1表示无条件计数器
        int count;        //计数数量
        int count_ptr;    //计数指针

        /*
        匹配状态机
        -1: 未匹配
        -1<matche<len-1: 正在匹配
        matche==len-1: 匹配成功
        */
        int matche;


        List<byte> tempForMatch;

    }
}
